﻿using Elastic.Apm.NetCoreAll;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using XYS.Core.Api.Middlewares;
using XYS.Core.Models;
using XYS.Core.Util.Helper;
using XYS.Service.Core.EventBus.Abstractions;
using XYS.Service.Core.Middlewares;
using XYS.Service.Core.Service;

namespace XYS.Service.Core
{
    /// <summary>
    /// 
    /// </summary>
    public static class WebApplicationExtension
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static WebApplication UseCore(this WebApplication app)
        {
            //允许跨域配置
            app.UseCors(c =>
            {
                c.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
            });
            // 路由配置
            app.UseRouting();

            //监听全局配置变化
            app.UseGlobalSettingChange(typeof(GlobalCoreSetting));

            //使用Swagger
            app.UseSwagger();
            //使用SwaggerUI
            app.UseSwaggerUI(c =>
            {
                c.RoutePrefix = "swagger-xys";
                c.DefaultModelExpandDepth(8);
                c.DefaultModelsExpandDepth(8);
                //自动增加swagger Endpoint
                var keys = SwaggerExtension.OpenApiInfoMap.Keys.Order().ToList();
                foreach (var key in keys)
                {
                    var item = SwaggerExtension.OpenApiInfoMap[key];
                    if (item.TermsOfService == null)
                        c.SwaggerEndpoint($"/swagger/{key}/swagger.json", key);
                    else
                        c.SwaggerEndpoint(item.TermsOfService.ToString(), key);
                }
            });

            //取消 自动重定向至 https
            app.UseForwardedHeaders();
            ILoggerFactory loggerFactory = null;

            //添加 Elastic APM 中间件
            string apmServerUrl = app.Configuration["ElasticApm:ServerUrl"];
            if (!string.IsNullOrWhiteSpace(apmServerUrl))
            {
                app.UseAllElasticApm(app.Configuration);
                var loggerFactoryObj = app.Services.GetService(typeof(ILoggerFactory));
                if (loggerFactoryObj != null && loggerFactoryObj is ILoggerFactory loggerFactoryTmp)
                {
                    loggerFactory = loggerFactoryTmp;
                    var logger = loggerFactory.CreateLogger("XYS.Core");
                    logger.LogWarning("已启用 APM 记录请求链路[{apmServerUrl}]", apmServerUrl);
                }
            }

            //xxl 请求中间件
            app.UseMiddleware<XxlJobExecutorMiddleware>();
            //启用 http请求处理 中间件
            app.UseMiddleware<HttpContextMiddleware>();
            

            //启用认证管道中间件
            app.UseAuthentication();
            //启用授权管道
            app.UseAuthorization();

            app.MapControllers();

            //启用事件总线订阅
            app.UseEventBus();


            //启用 gRpc
            app.UseGRpc(loggerFactory?.CreateLogger("UseGRpc"));

            TokenHelper.cache = app.Services.GetService<ICache>();
            TokenHelper.memoryCache = app.Services.GetService<IMemoryCache>();
            
            return app;
        }

    }
}
